#ifndef TS_MAP_INCLUDED
#define TS_MAP_INCLUDED

#include <map>

#include "SharedReaderUniqueWriter.h"
#include "NonCopyable.h"


template< class Key, class Value, class Compare = std::less< Key >, class Allocator = std::allocator< std::pair< const Key, Value > > >
class ThreadSafeMap: NonCopyable
{

public:
    ThreadSafeMap(void);
    ~ThreadSafeMap(void);


public:
    void set( const Key& key, const Value& value );
    Value get(const Key& key) const;
    void erase(const Key& key);

    size_t size() const;
    bool has(const Key& key) const;
    bool isEmpty() const;

private:
    std::map< Key, Value, Compare, Allocator > map_;
    mutable SharedReaderUniqueWriter readerWriter_;
};

template< class Key, class Value, class Compare , class Allocator >
ThreadSafeMap<Key, Value, Compare, Allocator>::ThreadSafeMap( void ) 
    : readerWriter_()
{

}

template< class Key, class Value, class Compare , class Allocator>
ThreadSafeMap<Key, Value, Compare, Allocator>::~ThreadSafeMap( void )
{
}


template< class Key, class Value, class Compare, class Allocator  >
void ThreadSafeMap<Key, Value, Compare, Allocator>::set( const Key& key, const Value& value )
{
    AutoWriterLocker locker(readerWriter_);

    map_[key] = value;
}


template< class Key, class Value, class Compare, class Allocator  >
Value ThreadSafeMap<Key, Value, Compare, Allocator>::get( const Key& key ) const 
{
    AutoReaderLocker locker(readerWriter_);

    return map_[key];
}

template< class Key, class Value, class Compare, class Allocator  >
void ThreadSafeMap<Key, Value, Compare, Allocator>::erase( const Key& key )
{
    AutoWriterLocker locker(readerWriter_);

    map_.erase(key);
}


template< class Key, class Value, class Compare, class Allocator  >
bool ThreadSafeMap<Key, Value, Compare, Allocator>::has(const Key& key) const
{
    AutoReaderLocker locker(readerWriter_);

    return map_.end() != map_.find[key];
}



template< class Key, class Value, class Compare, class Allocator  >
bool ThreadSafeMap<Key, Value, Compare, Allocator>::isEmpty() const
{
    AutoReaderLocker locker(readerWriter_);

    return map_.empty();
}


template< class Key, class Value, class Compare, class Allocator  >
size_t ThreadSafeMap<Key, Value, Compare, Allocator>::size() const 
{
    AutoReaderLocker locker(readerWriter_);

    return map_.size();
}

#endif//TS_MAP_INCLUDED